﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CdcSoftware.Pivotal.Applications.Core.Client;
using CdcSoftware.Pivotal.Engine.UI.Forms;
using System.Windows.Forms;
using System.Data;
using CdcSoftware.Pivotal.Applications.Core.Common;
using System.ComponentModel;
using CdcSoftware.Pivotal.Engine.Client.Services.Interfaces;
using CdcSoftware.Pivotal.Engine;
using System.Collections;
using CdcSoftware.Pivotal.Engine.Types.ServerTasks;
using System.Xml;
using System.Configuration;
using System.Reflection;
using Pcm.Retail.Client;
using Microsoft.PointOfService;
using System.Threading;
using CdcSoftware.Pivotal.Engine.Types.Localization;
using System.IO;
using System.Text.RegularExpressions;

namespace Pcm.Retail.Client.FormTasks
{
    public partial class RETender : FormClientTask
    {
        #region Variables
        //PosPrinter printer;
        OrderedEnumerableRowCollection<DataRow> sortedTC;
        private Form popupChange = null;
        private System.Windows.Forms.Button btnClose;
        private System.Windows.Forms.Label Total, Label2, lblTotal, lblChange;
        private System.Windows.Forms.TableLayoutPanel TableLayoutPanel1;
        bool popupPromptClosed = false;
        bool popUpShown = false;
        # endregion

        /// <summary>
        /// Close button click of the change prompt.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            try
            {
                popupPromptClosed = true;
                popupChange.Close();
            }
            catch (Exception ex)
            {
                Globals.HandleException(ex, true);
            }
        }

        /// <summary>
        /// On key down of the form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="argsEA"></param>
        public virtual void Form_KeyPress(PivotalControl sender, EventArgs argsEA)
        {
            try
            {
                KeyEventArgs args = argsEA as KeyEventArgs;
                if (TypeConvert.ToString(this.PrimaryDataRow["RE_Order_Status"]) != "Processed")
                {
                    //if (TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]).ToUpper() != "REFUND")
                    //{
                    if (Control.ModifierKeys == Keys.Shift && args.KeyCode == Keys.F1)
                        CashBtn_OnClick(sender, argsEA);
                    else if (Control.ModifierKeys == Keys.Shift && args.KeyCode == Keys.F2)
                        BackBtn_OnClick(sender, argsEA);
                    else if (Control.ModifierKeys == Keys.Shift && args.KeyCode == Keys.F10)
                        OthersBtn_OnClick(sender, argsEA);
                    else if (Control.ModifierKeys == Keys.Shift && args.KeyCode == Keys.F11)
                        CancelBtn_OnClick(sender, argsEA);
                    else if (args.KeyCode == Keys.F3)
                        NETSBtn_OnClick(sender, argsEA);
                    else if (args.KeyCode == Keys.F4)
                        VouchersBtn_OnClick(sender, argsEA);
                    else if (args.KeyCode == Keys.F6)
                        VISABtn_OnClick(sender, argsEA);
                    else if (args.KeyCode == Keys.F8)
                        MastersBtn_OnClick(sender, argsEA);
                    else if (args.KeyCode == Keys.F9)
                        AmexBtn_OnClick(sender, argsEA);
                    else if (args.KeyCode == Keys.F10)
                        IPPBtn_OnClick(sender, argsEA);
                    else if (args.KeyCode == Keys.F2)
                        CUPBtn_OnClick(sender, argsEA);
                    else if (args.KeyCode == Keys.F11)
                    {
                        this.FormControl.GetControlByName("btnProcess").Focus();
                        ProcessSale_OnClick(sender, argsEA);
                    }
                    //}
                    //else
                    //{
                    //    if (Control.ModifierKeys == Keys.Shift && args.KeyCode == Keys.F2)
                    //        BackBtn_OnClick(sender, argsEA);
                    //    else if (args.KeyCode == Keys.F4)
                    //        VouchersBtn_OnClick(sender, argsEA);
                    //    else if (Control.ModifierKeys == Keys.Shift && args.KeyCode == Keys.F10)
                    //        OthersBtn_OnClick(sender, argsEA);
                    //    else if (Control.ModifierKeys == Keys.Shift && args.KeyCode == Keys.F11)
                    //        CancelBtn_OnClick(sender, argsEA);
                    //    else if (args.KeyCode == Keys.F11)
                    //        ProcessSale_OnClick(sender, argsEA);
                    //}
                }
                else
                {
                    if (Control.ModifierKeys == Keys.Shift && args.KeyCode == Keys.F4)
                        AppleCareBtn_OnClick(sender, argsEA);
                }
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// On Secondary delete click
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// #Revision   Date        Author  Description
        /// 6.0.9.0     06/03/2012  DS      Initial Version
        /// </history>
        public virtual void OnSecondaryDeleteClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                DataTable orderTender = this.FormData.DataSet.Tables["RE_Order_Tender_Order_Id"];
                DataGridViewCellCancelEventArgs cancelEvent = args as DataGridViewCellCancelEventArgs;

                if (TypeConvert.ToString(orderTender.Rows[cancelEvent.RowIndex]["Tender_Type_Id__Tender_Type"]).ToUpper() == "CHANGE")
                {
                    PivotalMessageBox.Show("Change row can not be deleted manually.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    cancelEvent.Cancel = true;
                    return;
                }
                else
                {
                    //Show the pop-up for deletion
                    //DS: No pop-up needed according to 28th May Discussion.
                    //if (PivotalMessageBox.Show("Would you like to delete the selected record(s)?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    //{
                    //Delete change row before deleting Cash row.
                    if (TypeConvert.ToString(orderTender.Rows[cancelEvent.RowIndex]["Tender_Type_Id__Tender_Type"]).ToUpper() == "CASH")
                        DeleteChangeRow(orderTender, null);

                    //Delete the selected row.
                    orderTender.Rows.Remove(orderTender.Rows[cancelEvent.RowIndex]);
                    //}   

                    //DS: When there is another tendertype added with cashrow, and then the cash is increased(which will trigger the change row) and then the other 
                    //tendertype is deleted, the change row must be calculated again. And if required deleted also.
                    if (!(TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]) == "Refund"))
                        RecalculateChangeRow(orderTender);

                    cancelEvent.Cancel = true;
                }

                //Calculate the Tendered and Balance amount.
                TotalsCalculations();
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// Calculate the total amount on datagrid cell leave
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// #Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void AmountDataGridField_CellDataSourceUpdated(object sender, EventArgs args)
        {
            try
            {
                DataTable orderTender = this.FormData.DataSet.Tables["RE_Order_Tender_Order_Id"];
                int rowIndex = ((DataGridViewCellEventArgs)args).RowIndex;
                double extraAmt = 0;

                if (orderTender.Rows[rowIndex]["Tendered_Amount"] == DBNull.Value)
                {
                    TotalsCalculations();
                    return;
                }

                if (orderTender.Rows[rowIndex]["Tender_Type_Id__Tender_Type"] == DBNull.Value)
                {
                    PivotalMessageBox.Show("Please select Type before entering Amount.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    orderTender.Rows[rowIndex]["Tendered_Amount"] = DBNull.Value;
                    return;
                }
                else
                {
                    double roundAmt = Globals.RoundOffPrice(Math.Abs(Math.Round(TypeConvert.ToDouble(orderTender.Rows[rowIndex]["Tendered_Amount"]), 2)), this.PrimaryDataRow["RE_LOB_Id"]);

                    if (Math.Abs(TypeConvert.ToDouble(orderTender.Rows[rowIndex]["Tendered_Amount"])) != roundAmt)
                        orderTender.Rows[rowIndex]["Tendered_Amount"] = TypeConvert.ToDouble(orderTender.Rows[rowIndex]["Tendered_Amount"]) < 0 ? -roundAmt : roundAmt;

                    DataRow[] changeRow = orderTender.AsEnumerable().Where(a => TypeConvert.ToString(a["Tender_Type_Id__Tender_Type"]).ToUpper() == "CHANGE").ToArray();
                    DataRow[] cashRow = orderTender.AsEnumerable().Where(a => TypeConvert.ToString(a["Tender_Type_Id__Tender_Type"]).ToUpper() == "CASH").ToArray();

                    if (TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]) == "Refund")
                    {
                        if (TypeConvert.ToDouble(orderTender.Rows[rowIndex]["Tendered_Amount"]) >= 0)
                            orderTender.Rows[rowIndex]["Tendered_Amount"] = -TypeConvert.ToDouble(orderTender.Rows[rowIndex]["Tendered_Amount"]);

                        double sum = Globals.RoundOffPrice(orderTender.AsEnumerable().Where(a => TypeConvert.ToString(a["Tender_Type_Id__Tender_Type"]).ToUpper() != "CHANGE")
                                                        .Sum(a => TypeConvert.ToDouble(a["Tendered_Amount"])), this.PrimaryDataRow["RE_LOB_Id"]);

                        if (sum < TypeConvert.ToDouble(this.PrimaryDataRow["Quote_Total"]))
                        {
                            PivotalMessageBox.Show("Amount entered is more than the refund amount. Please modify the tender amounts.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            TotalsCalculations();
                            return;
                        }
                    }
                    else
                    {
                        if (TypeConvert.ToString(orderTender.Rows[rowIndex]["Tender_Type_Id__Tender_Type"]) == "Cash" || cashRow.Count() > 0)
                        {
                            double sum = orderTender.AsEnumerable().Where(a => TypeConvert.ToString(a["Tender_Type_Id__Tender_Type"]).ToUpper() != "CHANGE")
                                                            .Sum(a => TypeConvert.ToDouble(a["Tendered_Amount"]));
                            if (sum > TypeConvert.ToDouble(this.PrimaryDataRow["Quote_Total"]))
                            {
                                //DS: 12052013 - To cope with the Machine Epsilon Issue.
                                extraAmt = Math.Round(TypeConvert.ToDouble(this.PrimaryDataRow["Quote_Total"]) - sum, 2);
                                double cashAmt = cashRow.Sum(a => TypeConvert.ToDouble(a["Tendered_Amount"]));
                                //double changeAmt = changeRow.Sum(a => TypeConvert.ToDouble(a["Tendered_Amount"]));

                                if (TypeConvert.ToString(orderTender.Rows[rowIndex]["Tender_Type_Id__Tender_Type"]).ToUpper() != "CASH" && -extraAmt >= cashAmt)
                                {
                                    if (changeRow.Count() > 0)
                                        orderTender.Rows.Remove(changeRow[0]);

                                    orderTender.Rows.Remove(cashRow[0]);
                                    TotalsCalculations();
                                    //this.PrimaryDataRow["RE_Tendered_Amount"] = sum - cashAmt;
                                    //this.PrimaryDataRow["RE_Balance_Amount"] = extraAmt + cashAmt;
                                    return;
                                }

                                //Check if there is already a Change row added. If so do not add it again.
                                if (changeRow.Count() == 0)
                                {
                                    double roundPrice = Globals.RoundOffPrice(Math.Abs(Math.Round(extraAmt, 2)), this.PrimaryDataRow["RE_LOB_Id"]);
                                    if (roundPrice > 0)
                                    {
                                        base.NewSecondaryRecord("RE_Order_Tender_Order_Id");
                                        orderTender.Rows[orderTender.Rows.Count - 1]["Tender_Type_Id"] = TypeConvert.ToDBValue(Globals.ServerSqlFind("RE_Tender_Type", "Tender_Type", "Change"));
                                        orderTender.Rows[orderTender.Rows.Count - 1]["Tendered_Amount"] = -roundPrice;
                                        orderTender.Rows[orderTender.Rows.Count - 1]["Currency_Id"] = this.PrimaryDataRow["RE_Store_Id__Currency_Id"];

                                        PivotalSecondary secondary = this.FormControl.GetSecondary("RE_Order_Tender_Order_Id");
                                        secondary.Rows[orderTender.Rows.Count - 1].ReadOnly = true;
                                    }
                                }
                                else
                                {
                                    //Update the change row value.
                                    foreach (DataRow dr in orderTender.Rows)
                                    {
                                        if (TypeConvert.ToString(dr["Tender_Type_Id__Tender_Type"]).ToUpper() == "CHANGE")
                                        {
                                            double roundPrice = Globals.RoundOffPrice(Math.Abs(Math.Round(extraAmt, 2)), this.PrimaryDataRow["RE_LOB_Id"]);
                                            if (roundPrice > 0)
                                                dr["Tendered_Amount"] = -roundPrice;
                                            else
                                                //Delete the change row.
                                                orderTender.Rows.Remove(changeRow[0]);

                                            break;
                                        }
                                    }
                                }
                                this.PrimaryDataRow["RE_Tendered_Amount"] = sum;
                                this.PrimaryDataRow["RE_Balance_Amount"] = extraAmt < 0 ? -Globals.RoundOffPrice(Math.Abs(Math.Round(extraAmt, 2)),
                                    this.PrimaryDataRow["RE_LOB_Id"]) : Globals.RoundOffPrice(Math.Abs(Math.Round(extraAmt, 2)), this.PrimaryDataRow["RE_LOB_Id"]);
                                return;
                            }
                            else
                            {
                                //Check if there is already a Change row added. If so delete that.
                                if (changeRow.Count() > 0)
                                    orderTender.Rows.Remove(changeRow[0]);
                            }
                        }
                    }
                }

                //Calculate Totals.
                TotalsCalculations();
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// Show Report Receipt on Click of Process Sale button
        /// </summary>
        /// <param name="sender">PivotalControl</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// #Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void ProcessSale_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                //Process the sale only if Balance Amount is 0 or more on the shop i.e. negative
                if (TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]) == "Refund" && TypeConvert.ToDouble(this.PrimaryDataRow["RE_Balance_Amount"]) < 0)
                {
                    PivotalMessageBox.Show("For Refund, Process the sale only if Balance Amount is 0.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                if (TypeConvert.ToDouble(this.PrimaryDataRow["RE_Balance_Amount"]) <= 0)
                {
                    //Check for Mandatory fields filled or not
                    DataTable orderTender = this.FormData.DataSet.Tables["RE_Order_Tender_Order_Id"];

                    //check if all the fields are filled and that no unfilled records are present
                    if (orderTender.AsEnumerable().Count(a => TypeConvert.ToBoolean(a["Voucher"])) != orderTender.AsEnumerable().Count(a => a["Reference_ID"] != DBNull.Value))
                    {
                        PivotalMessageBox.Show("Voucher Serial # is mandatory for the Voucher tenders.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }

                    //When user has selected voucher as one of the tender modes and there is unused voucher value when the user clicks the "Process Sale", 
                    //Display a prompt to the user:
                    //"There is un-used voucher value in this transaction. Do you want to proceed?" Yes/No
                    //If user clicks "Yes", add the unused value as "Check" in the tender section automatically and proceed to Process Sale.
                    //if user clicks on "No", do not do anything.
                    DataRow[] voucherRows = orderTender.AsEnumerable().Where(a => TypeConvert.ToBoolean(a["Voucher"]) == true).ToArray();

                    //DS: 12052013 - To cope with the Machine Epsilon Issue.
                    double extraAmt = Math.Round(TypeConvert.ToDouble(this.PrimaryDataRow["Quote_Total"]) -
                        orderTender.AsEnumerable().Sum(a => TypeConvert.ToDouble(a["Tendered_Amount"])), 2);

                    if (extraAmt < 0 && voucherRows.Count() > 0)
                    {
                        double voucherValue = voucherRows.Sum(a => TypeConvert.ToDouble(a["Tendered_Amount"]));
                        if (voucherValue > -extraAmt)
                        {
                            if (PivotalMessageBox.Show("There is un-used voucher value in this transaction. Do you want to proceed?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                                AddMiscIncome(-extraAmt);
                            else
                                return;
                        }
                    }

                    //Do the above check for type exchange also
                    if (TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]) == "Exchange")
                    {
                        if (extraAmt < 0)
                        {
                            if (PivotalMessageBox.Show("There is un-used value in this Exchange transaction. Do you want to proceed?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                                AddMiscIncome(-extraAmt);
                            else
                                return;
                        }
                    }
                    //DS: 12052013 - For "Trade-In" also park the Misc Income aside if any difference.
                    else if(TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]) == "Trade-In")
                    {
                        if (extraAmt < 0)
                        {
                            if (PivotalMessageBox.Show("There is un-used value in this Trade-In transaction. Do you want to proceed?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                                AddMiscIncome(-extraAmt);
                            else
                                return;
                        }
                    }

                    //Once processed, set the order status to Processed.
                    this.PrimaryDataRow["RE_Order_Status"] = "Processed";

                    DataTable orderProduct = this.FormData.DataSet.Tables["SFA_Order__Product_SFA_Order_I"];

                    for (int i = 0; i < orderProduct.Rows.Count; i++)
                    {
                        orderProduct.Rows[i]["RE_Item_Ordinal"] = i + 1;
                        //NN 10062013:Added code to set RE_PO_Number for Aplle Care implementation.
                        orderProduct.Rows[i]["RE_PO_Number"] = this.PrimaryDataRow["RE_Receipt_Number"].ToString() + "/" + (i + 1).ToString().PadLeft(3, '0');
                    }

                    //DS: 17052013 - Processed should be always true as there is no Mobile job.
                    //Change for Mobile System:Start:
                    //if (this.SystemClient.SystemInformation.IsMobile)
                    //    this.PrimaryDataRow["RE_Processed"] = false;
                    //else
                    //    this.PrimaryDataRow["RE_Processed"] = true;
                    this.PrimaryDataRow["RE_Processed"] = true;
                    //Change for Mobile System:End:

                    if (!this.FormView.SaveRecord())
                        return;

                    //NN 10 Jun 2013:
                    //Added code to Call AppleCare Webservice and creating a new record in RE_RAE_Transcation
                    //The response from web-service will be entered in RE_RAE_Transcation and SFA_Order__Product.
                    if (string.Equals(TypeConvert.ToString(PrimaryDataRow["RE_Order_Status"]), "Processed"))
                    {
                        DataTable orderProduct1 = this.DataSet.Tables["SFA_Order__Product_SFA_Order_I"];
                        DataRow[] appleCareProducts = orderProduct1.AsEnumerable().Where(a => a["RE_RAE_Serial_Number"] != DBNull.Value).ToArray();
                        //Check if Apple Care Produtcs exists in this Order record.
                        if (appleCareProducts != null && appleCareProducts.Length > 0)
                        {
                            //Call AppleCare Webservice and create a new record in RE_RAE_Transcation
                            System.ComponentModel.BackgroundWorker backGroundWorker = new System.ComponentModel.BackgroundWorker();
                            backGroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(backGroundWorker_DoWork);
                            backGroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backGroundWorker_RunWorkerCompleted);
                            backGroundWorker.RunWorkerAsync(new object[] { this.SystemClient });                            
                        }
                    }

                    //Update Vouchers.
                    Globals.SystemClient.ExecuteServerTask("RE_Sale", "UpdateVouchers", new Type[] { typeof(DataSet) }, new object[] { this.DataSet });

                    //Added this code to create movement records for the Items in the Order Products.
                    if (Convert.ToString(this.PrimaryDataRow["RE_Order_Status"]) == "Processed") //Create Movements only for the Processed Sales
                        Globals.SystemClient.ExecuteServerTask("RE_Inventory_Transfer", "processInventory", new Type[] { typeof(string), typeof(string), typeof(object) },
                                        new object[] { "Sale", this.PrimaryDataRow["RE_Type"], TypeConvert.ToDBValue(this.RecordId) });

                    //On process sale, upsert the RE_Member_Bday_Disc_Quota for the contact and year with the correct value for used.
                    //( sum of quantity for rows where the b'day discount is used)
                    //try
                    //{
                    //    if (this.TransitionPointParameter.HasValidParameters())
                    //    {
                    //        int quantityWithBdayDisc = TypeConvert.ToInt32(this.TransitionPointParameter.GetUserDefinedParameter(2));
                    //        if (quantityWithBdayDisc != 0)
                    //        {
                    //            //RA:27/Aug/2012:Change for Mobile System:Start:
                    //            if (!this.SystemClient.SystemInformation.IsMobile)
                    //            {
                    //                Globals.SystemClient.ExecuteServerTask("RE_Sale", "MemberBdayDiscQuotaUsed", new Type[] { typeof(object), typeof(int) },
                    //                new object[] { this.PrimaryDataRow["Bill_To_Contact_Id"], quantityWithBdayDisc });
                    //            }
                    //            //Change for Mobile System:End:
                    //        }
                    //    }
                    //}
                    //catch
                    //{
                    //    //This needs to be confirmed whether this throws an exception or not. To be on the safer side.
                    //}

                    string customerType = TypeConvert.ToString(this.PrimaryDataRow["RE_Customer_Type"]);
                    //Change for Mobile System:Start:
                    if (!this.SystemClient.SystemInformation.IsMobile)
                    {
                        if (string.Equals(customerType, "Member"))
                        {
                            //Set the fields in the contact as this is a Member Sale..
                            Globals.SystemClient.ExecuteServerTask("RE_Sale", "UpdateContactForVIPMemberSale", new Type[] { typeof(object), typeof(object), typeof(object) },
                                new object[] { this.PrimaryDataRow["Bill_To_Contact_Id"], this.PrimaryDataRow["Quote_Total"], this.PrimaryDataRow["Total_Discount"] });
                        }
                        //Update Staff Purchase details.
                        else if (string.Equals(customerType, "Top Management") || string.Equals(customerType, "Staff"))
                        {
                            //Update the RE_Staff_Purchase records for the corresponding records in secondary
                            Globals.SystemClient.ExecuteServerTask("RE_Sale", "UpdateStaffPurchase", new Type[] { typeof(object), typeof(object) },
                               new object[] { this.RecordId, this.PrimaryDataRow["RE_Staff_Customer_Id"] });
                        }
                    }
                    //Change for Mobile System:End:

                    //Open the Cash Drawer.
                    //Check for the appropriate boolean in Tender Type to trigger the cash drawer.
                    DataRow[] DrawerRows = orderTender.AsEnumerable().Where(a => TypeConvert.ToBoolean(a["Trigger_Open_Drawer"]) == true).ToArray();
                    if (DrawerRows.Count() > 0)
                    {
                        //DS: Now the POSHardwares are working on the new AppDomain.
                        //DS: 20052013 - Spawnning new thread for POS hardwares.
                        //DS: 12062013 - Removing threading suspecting Crash issue due to this.
                        PosHardware.PerformActivity<PivotalCashDrawer>("CashDrawer", true, null, false, false, false, null, null, null, null, null);
                        //Thread cashDrawerThread = new Thread(() => PosHardware.PerformActivity<PivotalCashDrawer>("CashDrawer", true, null, false, false, false, null, null, null, null, null));
                        //cashDrawerThread.Start();                        
                    }

                    //Check for Change rows. If present show it in a pop-up.
                    DataRow[] changeRow = orderTender.AsEnumerable().Where(a => TypeConvert.ToString(a["Tender_Type_Id__Tender_Type"]).ToUpper() == "CHANGE").ToArray();
                    if (changeRow.Count() > 0)
                        ShowChangePopup(changeRow);

                    //Receipt Printing in Elush is achieved through Crystal Reports.
                    Globals.ShowModalReport("RE_Receipt", RecordFilter.IndividualRecord, this.RecordId, null);

                    //If the save receipt/create contact/send email throws any error, just ignore and proceed with the flow.
                    object contactId = null;
                    try
                    {
                        if (string.Equals(customerType, "Walk-In"))
                            contactId = Globals.SystemClient.ExecuteServerTask("RE_Sale", "SaveReceiptAndSendMail", new Type[] { typeof(Id), typeof(bool) }, new object[] { this.RecordId, true });
                        else
                            Globals.SystemClient.ExecuteServerTask("RE_Sale", "SaveReceiptAndSendMail", new Type[] { typeof(Id), typeof(bool) }, new object[] { this.RecordId, false });
                    }
                    catch (Exception)
                    { }
                    ////Print receipt.
                    //if (string.Equals(TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]), "Exchange"))
                    //    InitializeAndPrintReceipt(true, false, TypeConvert.ToBoolean(this.PrimaryDataRow["RE_Gift"]));
                    //else
                    //    InitializeAndPrintReceipt(false, false, TypeConvert.ToBoolean(this.PrimaryDataRow["RE_Gift"]));

                    //Check if the sale qualifies the Customer to be a Member. This only in case the Customer Type is Walk-In.
                    if (string.Equals(customerType, "Walk-In"))
                    {
                        double qualifyingAmount = TypeConvert.ToDouble(Globals.ServerSqlIndex("Employee", "RE_VIP_Qualifying_Amount",
                            this.SystemClient.UserProfile.EmployeeId));

                        if (TypeConvert.ToDouble(this.PrimaryDataRow["Quote_Total"]) >= qualifyingAmount)
                        {
                            //DS: When Offline, show appropriate message to the User
                            if (this.SystemClient.SystemInformation.IsMobile)
                                PivotalMessageBox.Show("The customer has qualified to become a Member." + Environment.NewLine +
                                       "Please make a note and Create the Member when Online.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            //The customer is eligible for membership. Pop-up the membership form with the Order details.
                            else if (PivotalMessageBox.Show("The customer has qualified to become a Member. Do you want to enroll?", MessageBoxButtons.YesNo,
                                MessageBoxIcon.Information) == DialogResult.Yes)
                            {
                                //Pop-Up the member create form with the relevant details.
                                //DS: Member creation form is now defined on the LOB. Show the appropriate form depending on the LOB.
                                if (!String.IsNullOrEmpty(TypeConvert.ToString(this.PrimaryDataRow["RE_LOB_Id__Create_Member_Form"])))
                                {
                                    TransitionPointParameter transParam = new TransitionPointParameter();
                                    ParameterList param = new ParameterList();
                                    transParam.Construct();
                                    transParam.AddDefaultColumn("RE_Create_Staff_Id", this.PrimaryDataRow["RE_Cashier_Id"]);
                                    transParam.AddDefaultColumn("RE_Membership_Reciept_No", this.PrimaryDataRow["RE_Receipt_Number"]);
                                    transParam.AddDefaultColumn("RE_Membership_Order_Id", TypeConvert.ToDBValue(this.RecordId));
                                    transParam.AddDefaultColumn("RE_Batch_Id", this.PrimaryDataRow["RE_Batch_Id"]);
                                    transParam.AddDefaultColumn("RE_Type", "Member");
                                    transParam.AddDefaultColumn("RE_Store_Id", this.PrimaryDataRow["RE_Store_Id"]);
                                    transParam.AddDefaultColumn("RE_LOB_Id", this.PrimaryDataRow["RE_LOB_Id"]);
                                    transParam.AddDefaultColumn("RE_Status", "Pending");
                                    object tierId = Globals.SqlIndex("Employee", "RE_Loyalty_Program_Tier_Id", this.SystemClient.UserProfile.EmployeeId);
                                    transParam.AddDefaultColumn("RE_Loyalty_Program_Tier_Id", tierId);
                                    transParam.AddDefaultColumn("RE_Loyalty_Program_Id", Globals.SqlIndex("RE_Loyalty_Program_Tier", "Program_Id", Id.Create(tierId)));
                                    transParam.SetUserDefinedParameter(1, true);
                                    transParam.CopyToParameterList(param);

                                    //Check if the contact record is already created in this sale on the Tender page. If so then just edit that record.
                                    Globals.ShowModalForm(TypeConvert.ToString(this.PrimaryDataRow["RE_LOB_Id__Create_Member_Form"]),
                                        (contactId != null) ? Id.Create(contactId) : null, param);
                                }
                                else
                                    PivotalMessageBox.Show("Create Member form is not defined for the LOB." + Environment.NewLine +
                                        "Please contact System Administrator.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                    }
                    else if (string.Equals(customerType, "Top Management"))
                    {
                        //Send email for Top Management purchase.
                        //DS: Send the Email only when the system is Online.
                        if (!this.SystemClient.SystemInformation.IsMobile)
                            Globals.SystemClient.ExecuteServerTask("RE_Sale", "SendTopManagementEmail", new Type[] { typeof(object), typeof(string), typeof(string) },
                                new object[] { this.RecordId, this.PrimaryDataRow["RE_Top_Management_Id__Email"], this.PrimaryDataRow["RE_Top_Management_FN_LN"] });
                    }

                    this.FormView.CloseForm(false);
                }
                else
                {
                    PivotalMessageBox.Show("Process the sale only if Balance Amount is 0 or negative.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc, true);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void backGroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

            if (e.Result == null)
            {
                PivotalMessageBox.Show("Unable to communicate with Apple Web Service." + Environment.NewLine 
                    + "Please contact System Administrator.", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                if (e.Result != null && !e.Cancelled)
                {
                    string[,] returnValues = (string[,])e.Result;
                    
                    string message = "AppleCare Registration/Cancellation Status:" + Environment.NewLine + Environment.NewLine +
                        "Serial Number" + "\t" + "Agreement#" ;

                    for (int j = 0; j < returnValues.GetLength(0); j++)
                    {
                        string agreementNumber = returnValues[j, 1].ToString();
                        if (agreementNumber == string.Empty)
                            agreementNumber = "Unable to Process";

                        message = message + Environment.NewLine + returnValues[j, 0].ToString() + "\t" + agreementNumber;
                    }

                    PivotalMessageBox.Show(message, MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        /// <summary>
        /// Do work when the background worker thread is called. Here the Server Task is called which calls the Apple Care Web service.
        /// Activity which follows post apple care registration also gets executed inside the server call.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void backGroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            try
            {
                object[] param = e.Argument as object[];
               
                CdcSoftware.Pivotal.Engine.ServerProxy.SystemClient sysClient = (CdcSoftware.Pivotal.Engine.ServerProxy.SystemClient)param[0];
               
                string[,] returnValues = (string[,])sysClient.ExecuteServerTask("RE_Sale", "CreateAppleCareProduct", new Type[] { typeof(DataSet) }, new object[] { this.DataSet });

                e.Result = returnValues;
            }
            catch
            {
            }
            finally
            {
            }
        }

        /// <summary>
        /// Setting the logic for mandatory field on particular tender type selected
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// #Revision   Date        Author  Description
        /// 6.0.12.1    11/02/2013  DS      Initial Version
        /// </history>
        public virtual void TenderTypeSelected_CellDataSourceUpdated(object sender, DataGridViewCellEventArgs args)
        {
            try
            {
                DataTable orderTender = this.FormData.DataSet.Tables["RE_Order_Tender_Order_Id"];

                if (TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]) == "Refund")
                {
                    if (String.Equals(TypeConvert.ToString(orderTender.Rows[args.RowIndex]["Tender_Type_Id__Type"]).ToUpper(), "IPP"))
                    {
                        orderTender.Rows[args.RowIndex]["Tender_Type_Id"] = DBNull.Value;
                        return;
                    }
                    return;
                }
                DataTable clonedTender = orderTender.Copy();
                clonedTender.Rows[args.RowIndex].Delete();
                clonedTender.AcceptChanges();
                DataRow[] cashRow = orderTender.AsEnumerable().Where(a => TypeConvert.ToString(a["Tender_Type_Id__Tender_Type"]).ToUpper() == "CASH").ToArray();

                if (orderTender.Rows[args.RowIndex]["Tender_Type_Id"] == DBNull.Value)
                {
                    DeleteChangeRow(orderTender, cashRow);
                    return;
                }
                else
                {
                    if (TypeConvert.ToBoolean(orderTender.Rows[args.RowIndex]["Voucher"]) || (clonedTender.AsEnumerable().Count(a => 
                        TypeConvert.ToString(a["Tender_Type_Id__Tender_Type"]) == TypeConvert.ToString(orderTender.Rows[args.RowIndex]["Tender_Type_Id__Tender_Type"])) == 0))
                    {
                        //Check if there is already a Change row added. If so delete that.                        
                        DeleteChangeRow(orderTender, cashRow);

                        //Update the amounts and calculate the totals.
                        AmountDataGridField_CellDataSourceUpdated(sender, args);
                    }
                    else
                    {
                        PivotalMessageBox.Show("Selected Type is already present. You can modify the Amount if required.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        orderTender.Rows[args.RowIndex]["Tender_Type_Id"] = DBNull.Value;
                    }
                }

                if (TypeConvert.ToBoolean(orderTender.Rows[args.RowIndex]["Voucher"]) && TypeConvert.ToBoolean(orderTender.Rows[args.RowIndex]["Tender_Type_Id__Default_"]))
                    EnableDisableDataGridCell(false, args.RowIndex, "RE_Order_Tender_Order_Id", "Tendered_Amount");
                else
                    EnableDisableDataGridCell(true, args.RowIndex, "RE_Order_Tender_Order_Id", "Tendered_Amount");

                if (TypeConvert.ToBoolean(orderTender.Rows[args.RowIndex]["Voucher"]))
                    OnDataSourceUpdatedVoucherSerial(sender, args);
                //if (TypeConvert.ToBoolean(orderTender.Rows[args.RowIndex]["Voucher"]) && !Convert.IsDBNull(orderTender.Rows[args.RowIndex]["Reference_Id"]))
                //    orderTender.Rows[args.RowIndex]["Reference_Id"] = DBNull.Value;
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        #region Tender Button Events
        /// <summary>
        /// Cash record to be added on the secondary
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void CashBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                AddRecordForTenderType("Cash");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// Visa record to be added on the secondary
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void VISABtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                AddRecordForTenderType("Visa");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// MasterCard record to be added on the secondary
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void MastersBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                AddRecordForTenderType("Master");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// JCB record to be added on the secondary
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void CUPBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                AddRecordForTenderType("CUP");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// Diners record to be added on the secondary
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void IPPBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                if (TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]) != "Refund")
                {
                    if (this.DataSet.Tables["SFA_Order__Product_SFA_Order_I"].AsEnumerable().Count(a => string.Equals(TypeConvert.ToString(a["RE_Product_Type"]).ToUpper(), "FEES FOR IPP")) > 0)
                        AddRecordForTenderType("IPP");
                    else
                        if (PivotalMessageBox.Show("Can't proceed with IPP as Fees for IPP is not added." + Environment.NewLine +
                            "Do you want to go back to Sales screen to add?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            this.FormView.CloseForm(true);
                            Globals.ShowForm("RE_Sale – Walk In", this.RecordId, null, ActionTargetWindow.Current);
                        }
                }
                //DS: 20052013 - For source order involving IPP, refund also needs to be through IPP. So adding only when there is a IPP involved.
                else
                    if (this.DataSet.Tables["SFA_Order__Product_SFA_Order_I"].AsEnumerable().Count(a => string.Equals(TypeConvert.ToString(a["RE_Product_Type"]).ToUpper(), "FEES FOR IPP")) > 0)
                        AddRecordForTenderType("IPP");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// Amex record to be added on the secondary
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void AmexBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                AddRecordForTenderType("Amex");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// Vouchers record to be added on the secondary
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void VouchersBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                if (TypeConvert.ToString(this.PrimaryDataRow["RE_Type"]) != "Refund")
                    AddRecordForTenderType("Voucher");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// NETS record to be added on the secondary
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void NETSBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                AddRecordForTenderType("Nets");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// Check record to be added on the secondary
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void CheckBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                AddRecordForTenderType("Check");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// On hit of Cancel button
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// 6.0.9.0    15/03/2012  NN      Changed the Functionality to Delete the record on Cancel Click.
        /// </history>
        public virtual void CancelBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                if (PivotalMessageBox.Show("Are you sure you want to delete this record?",
                    MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
                {
                    //Setting the value of Global Varaible to TRUE,then deleting this Sales record.
                    //This value is checked in "RE_Sale Walk-in" form ,
                    //If this is TRUE then we are closing "RE_Sale Walk-in" form without any process since the record is alreday deleted
                    Globals.SalesRecordDeleted = true;

                    this.DeleteRecord();
                    this.FormView.CloseForm(true);
                }
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// On hit of Back button
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void BackBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                if (this.FormData.DataSet.Tables["RE_Order_Tender_Order_Id"].Rows.Count > 0)
                {
                    if (PivotalMessageBox.Show("This will move you back to the Order screen. Do you wish to proceed?",
                        MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
                        this.FormView.CloseForm(true);
                }
                else
                    this.FormView.CloseForm(true);
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// On hit of Credit button
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void OthersBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                AddRecordForTenderType("Others");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }
        /// <summary>
        /// On hit of Credit button
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   11/02/2013  DS      Initial Version
        /// </history>
        public virtual void CreditBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                AddRecordForTenderType("Credit");
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// On hit of Apple Care button
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   19/06/2013  BS      Initial Version
        /// </history>
        public virtual void AppleCareBtn_OnClick(PivotalControl sender, EventArgs args)
        {
            try
            {
                Id RAETransactionId = Globals.ShowSingleSelectionList("RE_RAE Transactions for Order ?", "RAE Transations", "Select the RAE Transaction", new Id[] { Id.Create(this.PrimaryDataRow["SFA_Order_Id"]) }, new string[] { });
                
                if (RAETransactionId != null)
                {
                    Globals.ShowModalForm("RE_RAE_Transaction", RAETransactionId, null);
                }
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }
        #endregion

        /// <summary>
        /// Validate serial number on update of the secondary field.
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="args">EventArgs</param>
        /// <history>
        /// #Revision   Date        Author  Description
        /// 6.0.12.1    18/02/2013  DS      Initial Version
        /// </history>
        public virtual void OnDataSourceUpdatedVoucherSerial(object sender, DataGridViewCellEventArgs args)
        {
            try
            {
                if (popUpShown)
                    return;
                bool validVoucherSerial = false;
                DataTable tenders = this.FormData.DataSet.Tables["RE_Order_Tender_Order_Id"];
                if (!Convert.IsDBNull(tenders.Rows[args.RowIndex]["Reference_Id"]))
                {
                    if (TypeConvert.ToBoolean(tenders.Rows[args.RowIndex]["Tender_Type_Id__Default_"]))
                    {
                        //17-07-2013 - AS - Added Check to find duplicate Voucher Serial Numbers
                        if (tenders.AsEnumerable().Count(a => String.Equals(a["Reference_Id"],
                            TypeConvert.ToString(tenders.Rows[args.RowIndex]["Reference_Id"])) &&
                            Id.Equals(Id.Create(a["Tender_Type_Id"]),Id.Create(tenders.Rows[args.RowIndex]["Tender_Type_Id"]))) > 1)
                        {
                            popUpShown = true;
                            PivotalMessageBox.Show("This Voucher is already added in Tender.",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                            popUpShown = false;
                        }
                        else
                        {
                            //Do the voucher validation.
                            DataTable voucher = Globals.GetDataTable("RE_Voucher by Serial No?", new object[] { tenders.Rows[args.RowIndex]["Reference_Id"] },
                                "Product_Id", "RE_Product_Serial_No_Id");
                            if (voucher != null && voucher.Rows.Count == 1)
                            {
                                //Find the price of the Voucher from the price book.
                                DataTable price = Globals.GetDataTable("RE_SFA Product Price with Product ? and Currency ? and LOB ?", new object[]{ voucher.Rows[0]["Product_Id"],
                                        this.PrimaryDataRow["RE_Store_Id__Currency_Id"], this.PrimaryDataRow["RE_LOB_Id"]}, "Price");
                                if (price != null && price.Rows.Count == 1)
                                {
                                    //Set the amount and lock the field.
                                    tenders.Rows[args.RowIndex]["Tendered_Amount"] = price.Rows[0]["Price"];
                                    tenders.Rows[args.RowIndex]["Product_Serial_No_Id"] = voucher.Rows[0]["RE_Product_Serial_No_Id"];
                                    EnableDisableDataGridCell(false, args.RowIndex, "RE_Order_Tender_Order_Id", "Tendered_Amount");
                                    validVoucherSerial = true;
                                    TotalsCalculations();
                                    return;
                                }
                                else if (price != null && price.Rows.Count > 1)
                                {
                                    tenders.Rows[args.RowIndex]["Tendered_Amount"] = DBNull.Value;
                                    popUpShown = true;
                                    PivotalMessageBox.Show("Multiple pricing defined for the Voucher." + Environment.NewLine + "Please contact the Administrator.",
                                        MessageBoxButtons.OK, MessageBoxIcon.Stop);
                                    popUpShown = false;
                                }
                                else
                                {
                                    tenders.Rows[args.RowIndex]["Tendered_Amount"] = DBNull.Value;
                                    popUpShown = true;
                                    PivotalMessageBox.Show("No pricing data found for the Voucher." + Environment.NewLine + "Please contact the Administrator.",
                                            MessageBoxButtons.OK, MessageBoxIcon.Stop);
                                    popUpShown = false;
                                }
                            }
                            else
                            {
                                tenders.Rows[args.RowIndex]["Tendered_Amount"] = DBNull.Value;
                                popUpShown = true;
                                PivotalMessageBox.Show("No valid voucher found for the Serial#: " + tenders.Rows[args.RowIndex]["Reference_Id"],
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                                popUpShown = false;
                            }
                        }
                    }
                    else
                    {
                        tenders.Rows[args.RowIndex]["Product_Serial_No_Id"] = DBNull.Value;
                        return;
                    }
                }
                tenders.Rows[args.RowIndex]["Tendered_Amount"] = DBNull.Value;
                TotalsCalculations();
                if (!Convert.IsDBNull(tenders.Rows[args.RowIndex]["Reference_Id"]))
                    tenders.Rows[args.RowIndex]["Reference_Id"] = DBNull.Value;
                if (!Convert.IsDBNull(tenders.Rows[args.RowIndex]["Product_Serial_No_Id"]))
                    tenders.Rows[args.RowIndex]["Product_Serial_No_Id"] = DBNull.Value;
                //if (!validVoucherSerial)
                //    BeginEditSecondaryCell("RE_Order_Tender_Order_Id", "Reference_Id", args.RowIndex);
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        public virtual void OnDataSourceUpdatedEmail(PivotalControl sender, EventArgs args)
        {
            try
            {
                PivotalEmail currentControl = (PivotalEmail)sender;
                string emailAddress = currentControl.EmailAddress;

                if (!String.IsNullOrEmpty(emailAddress))
                {
                    if (!InteractionService.ValidateEmailAddress(emailAddress,true))
                    {
                        this.PrimaryDataRow["RE_Contact_Email"] = DBNull.Value;
                        System.ComponentModel.CancelEventArgs cancelArgs = args as System.ComponentModel.CancelEventArgs;
                        cancelArgs.Cancel = true;
                    }
                }

                //if (this.PrimaryDataRow["RE_Contact_Email"] != DBNull.Value)
                //{
                //    bool validEmail = ValidateEmailAddress(TypeConvert.ToString(this.PrimaryDataRow["RE_Contact_Email"]));
                //    if (!validEmail)
                //    {
                //        PivotalMessageBox.Show("Please enter a valid Email.", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                //        return;
                //    }
                //}
            }
            catch(Exception ex)
            {
                Globals.HandleException(ex);
            }
        }

        private bool ValidateEmailAddress(string emailAddress)
        {
            if (!string.IsNullOrEmpty(emailAddress) && (emailAddress.Length > 0))
            {
                Regex regex = new Regex(@"^([\w]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z]([-\w]*[0-9a-zA-Z])*\.)+[0-9a-zA-Z]{2,9})$");
                return regex.IsMatch(emailAddress);
            }
            return true;
        }
    }
}
